package com.mng.index12306.framework.starter.common.threadpool.support.eager;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description : 快速消费线程池
 * @Author : YuShaochao
 * @Date : 2024-04-27 13:31
 */
public class EagerThreadPoolExecutor extends ThreadPoolExecutor {
    public EagerThreadPoolExecutor(int corePoolSize,
                                   int maximumPoolSize,
                                   long keepAliveTime,
                                   TimeUnit unit,
                                   BlockingQueue<Runnable> workQueue,
                                   ThreadFactory threadFactory,
                                   RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory,handler);
    }

    private final AtomicInteger submittedTaskCount = new AtomicInteger(0);

    public int getSubmittedTaskCount() {
        return submittedTaskCount.get();
    }
    @Override
    protected void afterExecute(Runnable r, Throwable t) {

        submittedTaskCount.decrementAndGet();
    }
    @Override
    public void execute(Runnable command) {

        submittedTaskCount.incrementAndGet();
        try{
            super.execute(command);
        }catch (RejectedExecutionException e){
            TaskQueue taskQueue = (TaskQueue) super.getQueue();
            try{
                super.execute(command);
            }catch (RejectedExecutionException ex){
                try{
                    if( !taskQueue.retryOffer(command,0,TimeUnit.MILLISECONDS)){
                        submittedTaskCount.decrementAndGet();
                        throw new RejectedExecutionException("Queue capacity is full. ",ex);
                    }
                } catch (InterruptedException iex){
                    submittedTaskCount.decrementAndGet();
                    throw new RejectedExecutionException(iex);
                }
            } catch (Exception ex){
                submittedTaskCount.decrementAndGet();
                throw ex;
            }
        }
    }


}
